package com.lonely.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lonely.common.core.domain.Select;
import com.lonely.common.core.page.Condition;
import com.lonely.common.enums.CommonStatus;
import com.lonely.common.exception.BusinessException;
import com.lonely.common.utils.SecurityUtils;
import com.lonely.system.domain.dto.size.BatchAddSizeDto;
import com.lonely.system.domain.dto.size.SysSizePageQueryDto;
import com.lonely.system.domain.dto.size.SysSizeSubmitDto;
import com.lonely.system.domain.entity.SysSize;
import com.lonely.system.domain.vo.system.size.SysSizePageQueryVo;
import com.lonely.system.mapper.SysSizeMapper;
import com.lonely.system.service.ISysSizeService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author : 黄志标
 * @date: 2025/7/29 9:55
 * @description: 尺码服务实现类
 */
@Service
public class SysSizeServiceImpl extends ServiceImpl<SysSizeMapper, SysSize> implements ISysSizeService {


    /**
     * 分页查询
     *
     * @param queryDto
     * @return
     */
    @Override
    public Page<SysSizePageQueryVo> page(SysSizePageQueryDto queryDto) {
        Page<SysSize> page = Condition.page(queryDto);
        LambdaQueryWrapper<SysSize> queryWrapper = new LambdaQueryWrapper<SysSize>().like(StrUtil.isNotBlank(queryDto.getSizeName()), SysSize::getSizeName, queryDto.getSizeName())
                .eq(queryDto.getStatus() != null, SysSize::getStatus, queryDto.getStatus());

        Page<SysSize> sizePage = super.page(page, queryWrapper);
        Page<SysSizePageQueryVo> resultPage = new Page<>();
        BeanUtils.copyProperties(sizePage, resultPage);

        if (CollUtil.isNotEmpty(sizePage.getRecords())) {
            resultPage.setRecords(sizePage.getRecords().stream().map(x -> {
                SysSizePageQueryVo sysSizePageQueryVo = new SysSizePageQueryVo();
                BeanUtils.copyProperties(x, sysSizePageQueryVo);
                return sysSizePageQueryVo;
            }).collect(Collectors.toList()));
        }
        return resultPage;
    }

    /**
     * 创建尺码
     *
     * @param batchAddSizeDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(BatchAddSizeDto batchAddSizeDto) {
        // 去重
        List<String> sizeNames = batchAddSizeDto.getSizeNames().stream().filter(StrUtil::isNotBlank).distinct().collect(Collectors.toList());
        if (CollUtil.isEmpty(sizeNames)) {
            return;
        }

        // 校验
        this.batchCheckSizeName(sizeNames);

        List<SysSize> sizes = sizeNames.stream().map(x -> {
            SysSize sysSize = new SysSize();
            sysSize.setSizeName(x);
            sysSize.setCreateBy(SecurityUtils.getUserId());
            sysSize.setUpdateBy(SecurityUtils.getUserId());
            return sysSize;
        }).collect(Collectors.toList());
        super.saveBatch(sizes);
    }

    /**
     * 编辑尺码
     *
     * @param submitDto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(SysSizeSubmitDto submitDto) {
        Assert.notNull(submitDto.getId(), "参数错误(id)");
        checkSize(submitDto);
        SysSize oldSize = super.getById(submitDto.getId());
        BeanUtils.copyProperties(submitDto, oldSize);
        oldSize.setUpdateBy(SecurityUtils.getUserId());
        super.updateById(oldSize);
    }

    /**
     * 启用尺码
     *
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void enabled(Long id) {
        SysSize sysSize = super.getById(id);
        Assert.notNull(sysSize, "尺码不存在");
        sysSize.setStatus(CommonStatus.ENABLE.code);
        super.updateById(sysSize);
    }

    /**
     * 禁用尺码
     *
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void disable(Long id) {
        SysSize sysSize = super.getById(id);
        Assert.notNull(sysSize, "尺码不存在");
        sysSize.setStatus(CommonStatus.DISABLE.code);
        super.updateById(sysSize);
    }

    /**
     * 获取尺码穿梭框选项值
     *
     * @return
     */
    @Override
    public List<Select> getSizeTransferOptions() {
        return super.list(new LambdaQueryWrapper<SysSize>()
                .eq(SysSize::getStatus, CommonStatus.ENABLE.code)
        ).stream().map(x -> {
            Select select = new Select();
            select.setValue(Convert.toStr(x.getId()));
            select.setLabel(x.getSizeName());
            return select;
        }).collect(Collectors.toList());
    }

    /**
     * 获取商品尺码穿梭框选项值
     *
     * @return
     */
    @Override
    public List<Select> getGoodsSizeTransferOptions() {
        return super.list(new LambdaQueryWrapper<SysSize>()
                .eq(SysSize::getStatus, CommonStatus.ENABLE.code)
        ).stream().map(x -> {
            Select select = new Select();
            select.setValue(x.getSizeName());
            select.setLabel(x.getSizeName());
            return select;
        }).collect(Collectors.toList());
    }


    /**
     * 校验尺码信息
     *
     * @param submitDto
     */
    private void checkSize(SysSizeSubmitDto submitDto) {

        // 1. 校验尺码名称是否重复
        int count = super.count(new LambdaQueryWrapper<SysSize>()
                .eq(SysSize::getSizeName, submitDto.getSizeName())
                .ne(submitDto.getId() != null, SysSize::getId, submitDto.getId()));
        Assert.isTrue(count == 0, "该尺码已存在");

        //2. 校验尺码id是否正确
        if (submitDto.getId() != null) {
            SysSize sysSize = super.getById(submitDto.getId());
            Assert.notNull(sysSize, "尺码不存在");
        }
    }

    /**
     * 批量校验尺码名称信息
     *
     * @param sizeNames
     */
    private void batchCheckSizeName(List<String> sizeNames) {
        List<SysSize> sysSizes = super.list(new LambdaQueryWrapper<SysSize>()
                .in(SysSize::getSizeName, sizeNames)
        );
        if (CollUtil.isNotEmpty(sysSizes)) {
            String errorMsg = sysSizes.stream().map(SysSize::getSizeName).collect(Collectors.joining(",", "已存在以下尺码", ""));
            throw new BusinessException(errorMsg);
        }

    }


}
